package ltd.dujiabao.reserver.service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;
import ltd.dujiabao.reserver.constant.RequestHeaderConstant;
import ltd.dujiabao.reserver.domain.SubmitParam;
import ltd.dujiabao.reserver.domain.SubmitResult;
import ltd.dujiabao.reserver.util.HttpClientUtils;
import ltd.dujiabao.reserver.util.JsonUtils;

/**
 * @author : DuJiabao
 * @Project : reserver
 * @Time : 2021/11/6 11:38
 * @Desc : 提交预约表单
 */

@Slf4j
@Service
public class SubmitService {
    @Value("${reserver.submit.url}")
    public String submitUrl;

    /**
     * 执行提交预约表单操作
     *
     * @param cookie      cookie
     * @param submitParam 提交表单的对象，需要在外面先构造好参数
     * @return true表示提交成功，false表示提交失败
     */
    public boolean doSubmit(String cookie, SubmitParam submitParam) {
        Map<String, String> headers = new HashMap<>(8);
        headers.put("Cookie", cookie);
        headers = buildHeaders(headers);
        String url = submitUrl + "?t=" + System.currentTimeMillis();
        Map<String, String> data = new HashMap<>(1);
        data.put("formData", submitParam.toString());
        HttpResponse response = HttpClientUtils.doPost(url, headers, data, StandardCharsets.UTF_8);
        if (response != null) {
            try {
                String entity = EntityUtils.toString(response.getEntity());
                SubmitResult submitResult = JsonUtils.json2bean(entity, SubmitResult.class);
                Integer errorCode = submitResult.getError();
                switch (errorCode) {
                    case 0:
                        log.info("Submitting the booking form successfully, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return true;
                    case 1:
                        log.warn("Submitting the booking form fail, because of your authority, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return false;
                    case 2:
                        log.warn("Submitting the booking form fail, because it's overtime, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return false;
                    case 3:
                        log.warn("Submitting the booking form fail, because it's a redundant submit, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return false;
                    case 100:
                        log.warn("Submitting the booking form fail, because of validation code wrong, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return false;
                    case 101:
                        log.warn("Submitting the booking form fail, because of booking fully, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return false;
                    case 102:
                        log.warn("Submitting the booking form fail, because of healthy code file missing, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return false;
                    case 103:
                        log.warn("Submitting the booking form fail, because of route code file missing, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return false;
                    default:
                        log.warn("Submitting the booking form fail, error code: {}, booking in id: {}", errorCode, submitResult.getBookingInId());
                        return false;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.warn("Submitting the booking form fail.");
        return false;
    }

    /**
     * 构造一个header组成的map
     *
     * @param originHeaders 初始map
     * @return 返回增加了多个header之后的map
     */
    private static Map<String, String> buildHeaders(Map<String, String> originHeaders) {
        if (originHeaders == null) {
            originHeaders = new HashMap<>(8);
        }
        originHeaders.put(RequestHeaderConstant.HEADER_NAME_ACCEPT, "application/json, text/javascript, */*; q=0.01");
        originHeaders.put(RequestHeaderConstant.HEADER_NAME_ORIGIN, "https://libyy.utsz.edu.cn");
        originHeaders.put(RequestHeaderConstant.HEADER_NAME_X_REQUESTED_WITH, "XMLHttpRequest");
        originHeaders.put(RequestHeaderConstant.HEADER_NAME_USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400");
        originHeaders.put(RequestHeaderConstant.HEADER_NAME_REFERER, "https://libyy.utsz.edu.cn/member/booking-in/index.html");
        originHeaders.put(RequestHeaderConstant.HEADER_NAME_ACCEPT_ENCODING, "gzip, deflate, br");
        originHeaders.put(RequestHeaderConstant.HEADER_NAME_ACCEPT_LANGUAGE, "zh-CN,zh;q=0.9");
        return originHeaders;
    }
}
